Skip to content

ci: harden the build and API-pages workflows#843

Merged
SunsetDrifter merged 6 commits into
mainfrom
docs/ci-quick-fixes
Jul 22, 2026
Merged

ci: harden the build and API-pages workflows#843
SunsetDrifter merged 6 commits into
mainfrom
docs/ci-quick-fixes

Conversation

@SunsetDrifter

@SunsetDrifter SunsetDrifter commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Why

Two gaps in the pipeline around the recently-tracked lockfile and the :main image tag:

  • build_n_push had no concurrency group: two quick merges to main race the image push, and whichever finishes last wins the :main tag regardless of commit order — the server pulls :main, so an older build can silently ship.
  • generate_api_pages ran npm install on an unpinned Node and committed with git add -A + git push --force. Since package-lock.json is now tracked, a divergent macOS-resolved lockfile could be swept into the auto-commit; and a force-push from this workflow would rewrite main, destroying any PR merged during its multi-minute run.

What

build_n_push.yml

  • Per-ref concurrency group — main builds queue (never cancelled mid-push), superseded PR builds are cancelled.
  • permissions: contents: read.
  • PR path filter now also covers .dockerignore and package.json.

generate_api_pages.yml

  • Pin Node 20, npm installnpm ci (this workflow never changes dependencies, so it installs the lockfile exactly and can never rewrite it).
  • Sync the checkout to the branch tip before regenerating: a run queued behind another checks out the commit pinned at dispatch time, and regenerating against that stale base can let a file the newer spec removed silently survive the pre-push rebase.
  • Stage only src/pages/ipa/resources (change-check scoped to match).
  • Rebase onto the branch before pushing, and drop --force: if main moved during the run, the single generated-files commit replays cleanly on top; a genuine conflict fails the run loudly with main untouched. If anyone remembers a deliberate reason the push was --force, please flag it.
  • Concurrency group: several same-day dispatches happen (see run history); overlapping runs regenerate the same files.

scripts/git-dates.mjs

  • Warn (instead of staying silent) when per-page dates are skipped because git is unavailable or the clone is shallow — previously every page silently lost its "Updated" line and the sitemap lost <lastmod>.
  • Document the squash-merge assumption behind the single-pass git log --name-only walk; drop the unused per-file lookup.

CLAUDE.md

  • Note that npm run start warns under output: 'standalone' (safe to ignore locally; prod runs node server.js).

Summary by CodeRabbit

  • Bug Fixes
    • Improved CI reliability by serializing overlapping workflow runs and limiting cancellation behavior.
    • Prevented stale Docker image/tag pushes by only publishing when the ref still matches the remote.
    • Made API page regeneration safer by syncing to the latest branch tip, avoiding force-pushes, and skipping superseded runs.
    • Narrowed change detection so only the relevant generated content triggers updates.
  • Documentation
    • Clarified local startup warning behavior for standalone output.

… the lockfile

build_n_push: add a per-ref concurrency group so two quick merges to main can't race the :main tag (last push wins regardless of commit order, and the server auto-pulls :main); add permissions: contents: read; validate .dockerignore and package.json changes in the PR path filter.

generate_api_pages: pin Node 20 and switch npm install -> npm ci so the run can never rewrite the now-tracked package-lock.json with a divergent macOS-resolved tree; stage only src/pages/ipa/resources instead of git add -A; drop --force from the push — a force-push from this workflow would silently rewrite main and destroy any PR merged since its checkout.
…ookup

buildGitDateMap now logs a warning when it emits no dates (git missing or shallow clone) instead of silently blanking every page's Updated line and the sitemap lastmod entries; document the squash-merge assumption behind the --name-only walk. Remove the unused getGitLastModified. Note in CLAUDE.md that npm run start warns under output: 'standalone'. Gen output verified byte-identical.
Rebase the single generated-files commit onto the moved branch before pushing, so a PR merged during the multi-minute run no longer rejects the push (the failure --force was presumably papering over). A genuine conflict — a concurrent edit of the generated files themselves — still fails the run loudly with main untouched. Also serialise dispatches with a concurrency group: run history shows several same-day dispatches, and overlapping runs regenerate the same files.

Sandbox-tested against a bare repo: plain push rejected on race; rebase+push lands with both commits intact; true conflict exits 1 leaving the branch tip untouched.
A run queued behind another checks out the commit pinned at its dispatch time; regenerating against that stale base means the pre-push rebase replays a snapshot diff, and a file the newer spec removed can silently survive from the prior run. Fetch + reset to the branch tip before generating so the diff is computed against reality. Also note the latest-dispatched-vs-newest-tag caveat on the concurrency comment.

Sandbox-proven: with the old order a removed-in-newer-spec file survives the rebase replay; with sync-first it is gone.
@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@TechHutTV, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 27 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4f39fc76-855c-4f7e-9bbc-266849f77a8a

📥 Commits

Reviewing files that changed from the base of the PR and between a19a7d8 and a3aa189.

📒 Files selected for processing (1)
  • .github/workflows/build_n_push.yml
📝 Walkthrough

Walkthrough

This PR hardens two GitHub Actions workflows with concurrency, synchronization, deterministic installs, freshness checks, and safer publishing. It also refactors git date-map handling and warnings, and clarifies standalone startup documentation.

Changes

CI Workflow Updates

Layer / File(s) Summary
Build workflow trigger and freshness controls
.github/workflows/build_n_push.yml
Expands pull request path filters, restricts token permissions, configures concurrency, and prevents stale refs from pushing Docker images.
API page generation and safe publishing
.github/workflows/generate_api_pages.yml
Serializes dispatches, syncs to the branch tip, uses npm ci, scopes generated changes, skips superseded runs, and rebases before pushing.

Git Dates Script and Docs Update

Layer / File(s) Summary
Git-dates caching and warning behavior
scripts/git-dates.mjs
Removes the exported per-file lookup, adds date-map caching, updates merge and shallow-repository documentation, and logs git-history failures.
Start command documentation
CLAUDE.md
Documents the standalone-output warning and production server entrypoint.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Dispatcher
  participant Runner
  participant GitRemote
  participant DockerRegistry
  Dispatcher->>Runner: Start workflow with concurrency controls
  Runner->>GitRemote: Sync or check current branch/ref
  Runner->>Runner: Install dependencies and generate/build artifacts
  Runner->>DockerRegistry: Push only when the ref or dispatch is current
Loading

Possibly related PRs

  • netbirdio/docs#839: Also changes Node workflow setup from npm install to actions/setup-node@v4 with npm ci.

Poem

A rabbit locked the workflow gate,
Synced fresh branches before it was late.
With npm ci, pages bloom bright,
Stale pushes vanish out of sight.
Git dates warn, and docs now glow—
Hop hooray for safer flow! 🐰

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main CI workflow hardening across build and API-pages.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch docs/ci-quick-fixes

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/build_n_push.yml:
- Around line 70-95: Replace the separate freshness check and unconditional
action-level promotion in the “Check whether this ref is still current”/“Docker
build and push” flow with an atomic or conditionally coordinated final ref
validation and tag publication mechanism. Ensure an older non-PR run cannot
publish stale content after a newer commit advances the ref; do not rely solely
on a second check immediately before the existing push action.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d92fc721-3c08-4625-9f00-e3ca6792fb09

📥 Commits

Reviewing files that changed from the base of the PR and between 1800dfd and a19a7d8.

📒 Files selected for processing (2)
  • .github/workflows/build_n_push.yml
  • .github/workflows/generate_api_pages.yml
🚧 Files skipped from review as they are similar to previous changes (1)
  • .github/workflows/generate_api_pages.yml

Comment thread .github/workflows/build_n_push.yml Outdated
@TechHutTV TechHutTV self-assigned this Jul 22, 2026
@TechHutTV
TechHutTV self-requested a review July 22, 2026 15:06
@SunsetDrifter
SunsetDrifter merged commit 2a02ce7 into main Jul 22, 2026
4 checks passed
@SunsetDrifter
SunsetDrifter deleted the docs/ci-quick-fixes branch July 22, 2026 15:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants